#ifndef _BOOK_H_
#define _BOOK_H_

#include <string>
#include <list>
#include <iostream>

#include "Defs.h"

class Borrower_t;

class Book_t
{
public:

	/**
	* CTOR
	*/
	Book_t(const std::string& bookName, const std::string& author, ull bookISBN, size_t copies=1);

	/**
	* DTOR
	*/
	virtual ~Book_t();

	/**
	* Returns true if there are available copies.
	  O.W retunrs false
	*/
	inline bool isAvailable() const
	{
		return m_numAvailCopies > 0;
	}

	/**
	* Return number of copies of the book
	*/
	inline size_t numCopies() const
	{
		return m_numCopies;
	}

	/**
	* Return number of available copies
	**/
	inline size_t numAvailCopies() const
	{
		return m_numAvailCopies;
	}

	/**
	* Returns book's name
	**/
	inline const std::string& name() const
	{
		return m_bookName;
	}

	/**
	* Return book's ISBN
	**/
	inline ull isbn() const
	{
		return m_ISBN;
	}

	/**
	* Add borrower
	*/
	void addBorrower(Borrower_t* const borrower);

	/**
	* Add waiting borrower
	*/
	void addWaitingBorrower(Borrower_t* const borrower);

	/**
	* Returns true if someone is waiting for this book
	*/
	inline bool isSomeoneWaiting() const
	{
		return !m_waitingBorrowers.empty();
	}

	/**
	* Return true if borrwer has already borrowed the book or is on waiting list, according to listType
	*/
	bool alreadyBorrowed(Borrower_t* const borrower, int listType) const;

	/**
	* Borrower returns a book
	*/
	void returnBook(Borrower_t* borrower);

	/**
	* Returns a pointer to the borrower that is waiting for that book
	*/
	Borrower_t* whoWaits();

	/**
	* Return true if there are no borrowers and no waiting borrowers, so we can remove book from library
	*/
	inline bool safeToRemove() const
	{
		return (m_borrowers.empty() && m_waitingBorrowers.empty());
	}

	/**
	* Operator==
	*/
	bool operator==(const Book_t* other) const;


private:
	/**
	* Name of the book
	*/
	std::string m_bookName;

	/**
	* Name of author
	*/
	std::string m_bookAuthor;

	/**
	* Book's ISBN
	*/
	ull m_ISBN;

	/**
	* Number of total copies
	*/
	size_t m_numCopies;

	/**
	* Number of available copies
	*/
	size_t m_numAvailCopies;

	/**
	* List of book's borrowers
	*/
	typedef std::list<Borrower_t*> borrowersList;
	borrowersList m_borrowers;

	/**
	* List of waiting borrowers
	*/
	borrowersList m_waitingBorrowers;

	/**
	* Print book info
	**/
	friend std::ostream& operator<<(std::ostream&os, const Book_t& book);

	/**
	* COPY CTOR - no implementation
	**/
	Book_t(const Book_t& other);

	/**
	* Operator= - no implementation
	**/
	Book_t& operator=(const Book_t& other);
};

#endif // _BOOK_H_
